/**
 * 给一个树，每个点有权值，对点x，令
 * f(x) = SIGMA{Ci * d(x, i), i从1到N}
 * 求最小的f(x)
 * 令2是1的儿子，考虑f1与f2的区别，
 * f1 = C1 * d(1, 1) + C2 * d(1, 2) + ... + C[N] * d(1, N)
 * f2 = C1 * d(1, 2) + C2 * d(2, 2) + ... + C[N] * d(2, N)
 * f2 - f1 = C1 + SIGMA{Cj, j是1的父亲那边的节点} - SIGMA{Cj, j是2的子节点} = SIGMA{Cj, j是2的父亲那边的节点} - SIGMA{Cj, j是2的子节点}
 * 因此首先令1为根，做一个DP，求出SumFromFather与SumFromSon
 * 令fi=Di，首先求出D1，然后再做一遍深搜，每一次求出子节点的D
 * 同时可以求出最小值。
 * 
 * 标程有一种做法，是求加权重心。考虑Ci全为1，则本题就是求重心。
 * 重心的标准最大子树最小，加权重心的标准就是最大子树权值和最小
 * 求出重心，记作c，则f(c)就是答案
 */
#include <bits/stdc++.h>
using namespace std;

using llt = long long;
using vi = vector<int>;
using pii = pair<int, int>;
using vpii = vector<pii>;
using vll = vector<llt>;

template<typename T>
void input(vector<T> & a, int n){
    a.assign(n + 1, {});
    for(int i=1;i<=n;++i) cin >> a[i];
    return;
}

int N;
vector<vi> G;
vi Sz;
vi Depth;
vll C;
llt Ans;
llt Total;
vll SumFromFather, SumFromSon;
vll D;

void dfs(int u, int p){
    auto d = Depth[u];
    auto & s = Sz[u];
    s = 1;
    auto & sum = SumFromSon[u];
    sum = C[u];

    for(auto v : G[u]){
        if(v == p) continue;

        Depth[v] = Depth[u] + 1;
        dfs(v, u);
        s += Sz[v];
        sum += SumFromSon[v];
    }
    SumFromFather[u] = Total - sum;
    return;
}

void dp(int u, int p){
    auto d = D[u];

    for(auto v : G[u]){
        if(v == p) continue;

        D[v] = D[u] + SumFromFather[v] - SumFromSon[v];
        Ans = min(Ans, D[v]);
        dp(v, u);
    }   
    return;
}

void work(){
    cin >> N;
    G.assign(N + 1, {});
    for(int a,b,i=1;i<N;++i){
        cin >> a >> b;
        G[a].push_back(b);
        G[b].push_back(a);
    }
    input(C, N);

    Total = accumulate(C.begin() + 1, C.end(), 0LL);
    SumFromFather.assign(N + 1, 0);
    SumFromSon.assign(N + 1, 0);
    Depth.assign(N + 1, 0);
    Sz.assign(N + 1, 0);
    dfs(1, 0);

    D.assign(N + 1, 0LL);
    for(int i=1;i<=N;++i){
        D[1] += C[i] * Depth[i];
    }
    Ans = D[1];

    dp(1, 0);
    cout << Ans << endl;
    return;
}

int main(){
#ifndef ONLINE_JUDGE
    freopen("z.txt", "r", stdin);
#endif
    ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
    int nofkase = 1;
    // cin >> nofkase;
    while(nofkase--) work();
    return 0;
}